/****************************************
 * Auther:  Caffreyfans
 * Date:    2020-05-17
 * Description: MQTT to IR
 ***************************************/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Ethernet.h>
#include <ESP8266httpUpdate.h>
#include <ESP8266WebServer.h>
#include "ioUDP.h"
#include "ioOTA.h"
#include "ioMQTT.h"
#include "ioSerial.h"
#include "ioMsgHandler.h"
#include "ioUserSettings.h"
#include "ESP8266HTTPClient.h"
#include "ioIR.h"
#include "ioWebserver.h"
#include "iodevice.h"
#include "HLW9032.h"

/* update MAC and IP to the server */
void registerDevice();
StaticJsonDocument<1024> udppack;
void ICACHE_RAM_ATTR resetHandle();
uint32_t last_system_time = millis();
uint32_t system_time;
uint8_t devstas = 0;

void resetHandle()
{
    static unsigned long last_interrupt_time = millis();
    unsigned long interrupt_time = millis();
    static unsigned long start_time = millis();
    unsigned long end_time = millis();
    if (interrupt_time - last_interrupt_time > 10)
    {
        start_time = millis();
    }
    last_interrupt_time = interrupt_time;
    if (end_time - start_time > 3000)
    {
        settingsClear();
    }
}


/*******************************************************************************
* function name: registerDevice()
* input par    : 
* return       : 无
* description  : 注册设备，将设备ip地址发送到服务器
******************************************************************************/
void registerDevice()
{
    HTTPClient http;
    String head = "http://www.gpio.com.cn/iolight/iolight.ashx?ipinfo=" + WiFi.localIP().toString()+"&devid="+String(ESP.getChipId());
    Serial.println(head);
    http.begin(head);
    int http_code = http.GET();
    String mqttinfo = http.getString();
    Serial.println(mqttinfo);
}

void init_wifi()
{
    if (WiFi.SSID() != "")
    {
        WiFi.begin();
        if (WiFi.getAutoReconnect() == false)
        {
            WiFi.setAutoReconnect(true);
        }
        Serial.printf("sta configed %s\n", WiFi.SSID().c_str());
    }
    else
    {
        WiFi.mode(WIFI_AP_STA); //配置为AP模式
        String chip_id = String(ESP.getChipId(), HEX);
        chip_id.toLowerCase();
        String apName = ("io_" + chip_id); // 2 设置WIFI名称
        const char *softAPName = apName.c_str();
        WiFi.softAP(softAPName);          // 3创建wifi  名称 +密码 adminadmin
        IPAddress myIP = WiFi.softAPIP(); // 4输出创建的WIFI IP地址
        Serial.print("AP IP address: ");
        Serial.println(myIP);
        Serial.println("");
    }
}

void setup()
{
    Serial.begin(4800);

    DEV_Init();
    pinMode(reset_pin, INPUT_PULLUP);

    digitalWrite(reset_pin, HIGH);
    attachInterrupt(digitalPinToInterrupt(reset_pin), resetHandle, ONLOW);
    DEBUGF("%s", ESP.getCoreVersion().c_str());
    init_wifi();

    settingsLoad();

    udpInit();
    mqttInit();

    webserver_init();
}



void loop()
{
    static uint ippost = 0;
    static uint32_t udptick = millis();
    char *msg = udpRecive();
    webserverLoop();

#if (HAS_IRF==1)
    recvRaw();
#endif

    void hlw_loop();
    hlw_loop();

    DEV_Loop();
    if (msg)
    {
        recv_msg_doc.clear();
        DeserializationError error = deserializeJson(recv_msg_doc, msg);
        if (error)
        {
            ERRORLN("Failed to parse udp message");
        }
        msgHandle(&recv_msg_doc, MsgType::udp);
    }

    system_time = millis();
    if (system_time - udptick > 3000)
    {
        udptick = system_time;
        if (WiFi.status() == WL_CONNECTED)
        {
            if (ippost == 0)
            {
                registerDevice();
                ippost = 1;
            }
        }
        else
        {
            ippost = 0;
        }

        //mqtt断开 或是未禁止udp广播
        if ((!mqttConnected()) || (ConfigData.containsKey("nobroad") == false) || (ConfigData["nobroad"] == 0))
        {
            udppack.clear();
            udppack["cmd"] = "io";
            udppack["stas"] = devstas;
            udppack["volt"] = HLW8032_data.volt_value*1.88;
            udppack["curr"] = HLW8032_data.curr_value;
            udppack["power"] = HLW8032_data.power_value;

            IPAddress ip;
            if ((WiFi.status() == WL_CONNECTED) && (WiFi.softAPgetStationNum() == 0))
            {
                ip.fromString("255.255.255.255");
            }
            else
            {
                Serial.printf("broad ap:%d", WiFi.softAPgetStationNum());
                ip.fromString("192.168.4.255");
            }

            sendUDP(&udppack, ip);
        }
    }
    if (system_time - last_system_time > MQTT_RECONNECT_INTERVAL)
    {

        DEBUGLN("sCheck mqtt connection status");
        if (!mqttConnected())
        {
            DEBUGLN("MQTT disconnect, try to reconnect");
            mqttDisconnect();
            mqttReconnect();
        }
        last_system_time = system_time;
    }

    /* 接收 MQTT 消息 */
    mqttLoop();
}
